home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 316_01 / as8.c < prev    next >
Text File  |  1990-05-14  |  32KB  |  1,683 lines

  1. /*
  2.  * z8   assembler hgw july 1983: h.-g. willers
  3.  *
  4.  *      register syntax:
  5.  *              register:               r0 - r127, r240 - r255
  6.  *              working register:       w0 - w15
  7.  *
  8.  */
  9. #include <stdio.h>
  10. #include <setjmp.h>
  11.  
  12. #define NCPS    33    /* number of characters per symbol */
  13. #define NCPLE   NCPS+2  /* number of characters per listing element */
  14. #define NLEPL   1       /* number of listing elements per line */
  15. #define    NBIN    32
  16. #define NTSYM   512     /* length of numeric-label table */
  17. #define NERR    10
  18. #define NINPUT    128
  19. #define NCODE    128
  20. #define NTIT    64
  21. #define HASHSIZ 503     /* hashtable size */
  22.             /* must be prime */
  23.             /* more primes:    */
  24.             /* 503, 607, 701, 809, 907, 1009 */
  25.             /* see: handbook of math. functions p. 879 */
  26.  
  27. #define NLIST    0
  28. #define SLIST    1
  29. #define ALIST    2
  30. #define CLIST    3
  31.  
  32. typedef    unsigned addr_t;
  33.  
  34. struct    sym
  35. {
  36.     char    *s_name;
  37.     char    s_type;
  38.     char    s_flag;
  39.     addr_t    s_addr;
  40. };
  41.  
  42. #define S_UND    0
  43. #define S_ABS    1
  44.  
  45. #define S_OP0   2
  46. #define S_OP2   4
  47. #define S_OP3   5
  48. #define S_OP4   6
  49. #define S_OP5   7
  50. #define S_OP6   8
  51. #define S_OP7   9
  52. #define S_OP8   10
  53. #define S_OP9   11
  54. #define S_OP10  12
  55. #define S_OP11  13
  56. #define S_OP12  14
  57. #define S_OP13  15
  58. #define S_OP14  16
  59. #define S_OP15  17
  60.  
  61. #define S_LIT   19
  62. #define S_REG   20
  63. #define S_WREG  21
  64. #define S_IR    22              /* register indirect */
  65. #define S_WIR   23              /* working register indirect */
  66. #define S_INDEX 24
  67.  
  68. #define    S_WORD    25
  69. #define S_ASCII    26
  70. #define S_ASCIZ    27
  71. #define S_BLKB    28
  72. #define S_PAGE    29
  73. #define S_TITLE    30
  74. #define S_BYTE    31
  75. #define S_HLIST    32
  76. #define S_OLIST    33
  77. #define S_INTEL    34
  78. #define S_MKBUG    35
  79. #define    S_LIST 36
  80. #define S_NLIST 37
  81. #define S_START 38
  82.  
  83. #define WRMASK  0xe0            /* msbs for  working reg. add. */
  84. #define CALL    0xd6            /* direct call */
  85. #define CALLI   0xd4            /* indirect call */
  86. #define SOB     0x0a            /* sob-instruction */
  87. #define JUMP    0x8d            /* jump-always instruction */
  88. #define JUMPI   0x30            /* jump indirect */
  89. #define SRP     0x31
  90. #define INCW    0x0e            /* inc working register */
  91.  
  92. #define    S_MDF    01        /* Mult. def */
  93. #define S_ASG    02        /* Assigned def */
  94.  
  95. struct    tsym
  96. {
  97.     int    t_num;
  98.     addr_t    t_addr;
  99. };
  100.  
  101. struct    tsymp
  102. {
  103.     struct    tsym *t_fp;
  104.     struct    tsym *t_bp;
  105. };
  106.  
  107. struct    addr
  108. {
  109.     char    a_type;
  110.     char    a_reg;
  111.     addr_t    a_addr;
  112. };
  113.  
  114. int    line;
  115. int    page;
  116. int    lop;
  117. int    pass;
  118. int    ntsym;
  119. int    sflag = 0;        /* symbol-table-flag */
  120. int    lflag;
  121. int    nflag;
  122. int    eflag;
  123. addr_t    laddr;
  124. int    lmode;
  125. int    ldis = 0;        /* listing disable */
  126.                 /* =1 listing is disabled */
  127. int     hlist = 1;              /* hex listing is default */
  128. int    ninst = 0;        /* number of installs into symbol table */
  129. char    *ep;
  130. char    eb[NERR];
  131. char    *ip;
  132. char    ib[NINPUT];
  133. char    *cp;
  134. char    cb[NCODE];
  135. char    tb[NTIT];
  136. int    bo;
  137. int    ba;
  138. char    bb[NBIN];
  139.  
  140. unsigned int    startadr = 0xffff;      /* start address */
  141.  
  142. char liname[80];
  143. char obname[80];    /* listing and object filenames */
  144. char stbnam[80];
  145.  
  146. jmp_buf env;
  147.  
  148. long    daytime;
  149.  
  150. long    time();
  151. char *ctime();
  152. char *malloc();
  153. struct sym *lookup();
  154. struct sym *addr1();
  155.  
  156. struct sym *dot;    /* pointer to . value into symbol table */
  157.  
  158. struct sym sym[HASHSIZ] = {0};    /* space for symbol table */
  159.  
  160. extern struct sym optab[];
  161.  
  162. struct    tsym tsym[NTSYM];
  163. struct    tsymp tsymp[10];
  164.  
  165. /* lower opcode nibbles for class-8 opcodes */
  166. /* ordered as follows:  destination, source, nibble */
  167. /* table ends at zero destination */
  168.  
  169. char c8nib[] = { S_WREG, S_WREG, 2,
  170.         S_WREG, S_WIR, 3,
  171.         S_WREG, S_WREG, 4,
  172.         S_WREG, S_REG, 4,
  173.         S_REG, S_WREG, 4,
  174.         S_REG, S_REG, 4,
  175.         S_WREG, S_WIR, 5,
  176.         S_WREG, S_IR, 5,
  177.         S_REG, S_WIR, 5,
  178.         S_REG, S_IR, 5,
  179.         S_WREG, S_LIT, 6,
  180.         S_REG, S_LIT, 6,
  181.         S_WIR, S_LIT, 7,
  182.         S_IR, S_LIT, 7,
  183.         0, 0, 0
  184.         };
  185.  
  186. char movtab[] = { S_WREG, S_LIT, 0x0c,
  187.         S_WREG, S_REG, 0x08,
  188.         S_WREG, S_WREG, 0x08,
  189.         S_REG,  S_WREG, 0x09,
  190.         S_WREG, S_INDEX, 0xc7,
  191.         S_INDEX, S_WREG, 0xd7,
  192.         S_WREG, S_WIR, 0xe3,
  193.         S_WIR, S_WREG, 0xf3,
  194.         S_REG, S_REG, 0xe4,
  195.         S_REG, S_IR, 0xe5,
  196.         S_REG, S_LIT, 0xe6,
  197.         S_IR, S_LIT, 0xe7,
  198.         S_IR, S_REG, 0xf5,
  199.         S_WIR, S_REG, 0xf5,
  200.         S_IR, S_WREG, 0xf5,
  201.         S_WIR, S_WREG, 0xf5,
  202.         0, 0, 0
  203.         };
  204.  
  205. char c13tab[] = {S_WREG, S_WIR, 1,
  206.         S_WIR, S_WREG, 2,
  207.         0, 0, 0
  208.         };
  209.  
  210. FILE    *lfp;
  211. FILE    *ofp;
  212. FILE    *sfp;
  213.  
  214. char *strrchr();
  215. char *strchr();
  216.  
  217. main(argc, argv)
  218. char *argv[];
  219. {
  220.     register char *p;
  221.     register c, i;
  222.     struct tsym *tp;
  223.     char *iptr;        /* index-pointer */
  224.     char *fn;
  225.     FILE *afile();
  226.  
  227.     fn = NULL;
  228.     for (i=1; i<argc; ++i) {
  229.         p = argv[i];
  230.         if (*p == '-') {
  231.             ++p;
  232.             while (c = *p++)
  233.                 switch(c) {
  234.  
  235.                 case 'l':
  236.                 case 'L':
  237.                     ++lflag;
  238.                     break;
  239.  
  240.                 case 'n':
  241.                 case 'N':
  242.                     ++nflag;
  243.                     break;
  244.  
  245.                 default:
  246.                     fprintf(stderr, "%c: ignored.\n", c);
  247.                 }
  248.         } else
  249.             fn = p;
  250.     }
  251.     if (fn != NULL) {
  252.         sfp = afile(fn, 0);
  253.         if((iptr = strrchr(fn, '/')) == NULL)
  254.             strcpy(liname, fn);
  255.         else
  256.             strcpy(liname, ++iptr);
  257.         if((iptr = strrchr(liname, '.')) != NULL)
  258.             *iptr = 0;              /* truncate suffix (if any) */
  259.         if (!nflag) {
  260.             strcpy(obname, liname);
  261.             strcat(obname, ".o");
  262.         }
  263.         if (lflag) {
  264.             strcat(liname, ".l");
  265.             lfp = afile(liname, 1);
  266.         }
  267.         if(strcmp (fn, obname) == 0) {
  268.             fprintf(stderr, "Would overwrite %s\n", fn);
  269.             exit(1);
  270.         }
  271.         ofp = afile(obname, 1);
  272.         for (pass=0; pass<2; ++pass) {
  273.             if(pass == 0)
  274.                 insopc();          /* install opcodes */
  275.             dot = lookup(".", 0, 0);   /* locate . in table */
  276.             dot->s_type = S_ABS;
  277.             dot->s_flag = S_ASG;
  278.             dot->s_addr = 0;
  279.             line = 0;
  280.             page = 1;
  281.             lop =  60;
  282.             if (pass == 1) {
  283.                 rewind(sfp);
  284.                 for (i=0; i<10; ++i) {
  285.                     tsymp[i].t_fp = NULL;
  286.                     tsymp[i].t_bp = NULL;
  287.                     tp = tsym;
  288.                     while (tp < &tsym[ntsym]) {
  289.                         if (tp->t_num == i) {
  290.                             tsymp[i].t_fp = tp;
  291.                             break;
  292.                         }
  293.                         ++tp;
  294.                     }
  295.                 }
  296.             }
  297.             while (fgets(ib, sizeof ib, sfp) != NULL) {
  298.                 iptr = strchr(ib,'\n');
  299.                 *iptr = 0;
  300.                 ++line;
  301.                 cp = cb;
  302.                 ep = eb;
  303.                 ip = ib;
  304.                 eflag = 0;
  305.                 setjmp(env);
  306.                 if (eflag == 0)
  307.                     xasm();
  308.                 if (pass == 1) {
  309.                     diag();
  310.                     list();
  311.                 }
  312.             }
  313.         }
  314.         if (!nflag) {
  315.             bflush();
  316.             beof();
  317.         }
  318.         prstb();
  319.         prstat();
  320.     }
  321. }
  322.  
  323. FILE *
  324. afile(fn, wf)
  325. char *fn;
  326. {
  327.     register FILE *fp;
  328.  
  329.     fp = fopen(fn, wf?"w":"r");
  330.     if (fp == NULL) {
  331.         fprintf(stderr, "%s: cannot open.\n", fn);
  332.         exit(1);
  333.     }
  334.     return (fp);
  335. }
  336.  
  337. xasm()
  338. {
  339.     register c;
  340.     register addr_t a;
  341.     struct sym *sp;
  342.     struct tsym *tp;
  343.     int b, d, op;
  344.     char *p, id[NCPS];
  345.     struct addr a1, a2;
  346.  
  347.     laddr = dot->s_addr;
  348.     lmode = SLIST;
  349. loop:
  350.     while ((c = getnb()) == ';')
  351.         ;
  352.     if (c == 0 || c == '/')
  353.         return;
  354.     if (isdigit(c)) {
  355.         if (getnb() != ':')
  356.             err('q');
  357.         c -= '0';
  358.         if (pass == 0) {
  359.             if (ntsym >= NTSYM)
  360.                 error("Too many temp. symbols!\n");
  361.             tsym[ntsym].t_num = c;
  362.             tsym[ntsym].t_addr = dot->s_addr;
  363.             ++ntsym;
  364.         }
  365.         else {
  366.             tp = tsymp[c].t_fp;
  367.             tsymp[c].t_bp = tp;
  368.             tsymp[c].t_fp = NULL;
  369.             ++tp;
  370.             while (tp < &tsym[ntsym]) {
  371.                 if (tp->t_num == c) {
  372.                     tsymp[c].t_fp = tp;
  373.                     break;
  374.                 }
  375.                 ++tp;
  376.             }
  377.         }
  378.         goto loop;
  379.     }
  380.     if (!isidc(c))
  381.         err('q');
  382.     getid(c, id);
  383.     if ((c = getnb()) == ':') {
  384.         sp = lookup(id, 1, 0);
  385.         if (pass == 0) {
  386.             if (sp->s_type!=S_UND && (sp->s_flag&S_ASG)==0)
  387.                 sp->s_flag |= S_MDF;
  388.             sp->s_type = S_ABS;
  389.             sp->s_addr = dot->s_addr;
  390.         } else {
  391.             if ((sp->s_flag&S_MDF) != 0)
  392.                 err('m');
  393.             if (sp->s_type!=S_ABS || sp->s_addr!=dot->s_addr)
  394.                 err('p');
  395.         }
  396.         lmode = ALIST;
  397.         goto loop;
  398.     }
  399.     if (c == '=') {
  400.         sp = lookup(id, 1, 0);
  401.         if (sp->s_type!=S_UND && (sp->s_flag&S_ASG)==0)
  402.             err('m');
  403.         expr(&a1);
  404.         sp->s_addr = laddr = a1.a_addr;
  405.         sp->s_flag = S_ASG;
  406.         sp->s_type = a1.a_type;
  407.         lmode = ALIST;
  408.         goto loop;
  409.     }
  410.     unget(c);
  411.     lmode = CLIST;
  412.     if ((sp=lookup(id, 0, 0)) == NULL) {
  413.         err('o');
  414.         return;
  415.     }
  416.     op = sp->s_addr;
  417.     switch(sp->s_type) {
  418.  
  419.     case S_HLIST:
  420.     case S_OLI